{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a3a19fb0",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "#  8\\.  回归模型评价与检验  # \n",
    "\n",
    "##  8.1.  介绍  # \n",
    "\n",
    "目前为止，我们已经掌握了回归分析与预测的相关方法，并了解了多种模型评价的标准。不过，对于回归分析的结果，往往还需要经历一个流程，那就是：假设检验，而这个过程就会运用到数理统计学的相关知识。 \n",
    "\n",
    "##  8.2.  知识点  # \n",
    "\n",
    "  * 拟合优度检验 \n",
    "\n",
    "  * 变量显著性检验 \n",
    "\n",
    "对于回归预测结果，通常会有平均绝对误差（MAE)，均方误差（MSE），平均绝对百分比误差（MAPE）等 3 个指标进行评价。其中，MAE 和 MSE 在线性回归和多项式回归的实验中已经有所介绍，下面重新回顾并补充 MAPE 的计算公式。 \n",
    "\n",
    "平均绝对误差（MAE）就是绝对误差的平均值，它的计算公式如下： \n",
    "\n",
    "$$ \\operatorname{MAE}(y, \\hat{y})=\\frac{1}{n} \\sum_{i=1}^{n}\\left|y_{i}-\\hat{y}_{i}\\right| \\tag{1} $$ \n",
    "\n",
    "均方误差（MSE）表示误差的平方的期望值，它的计算公式如下： \n",
    "\n",
    "$$ \\textrm{MSE}(y, \\hat{y} ) = \\frac{1}{n} \\sum_{i=1}^{n} (y_i - \\hat{y}_{i})^{2} \\tag{2} $$ \n",
    "\n",
    "平均绝对百分比误差（MAPE）。MAPE 是 MAD 的变形，它是一个百分比值，因此比其他统计量更容易理解。例如，如果 MAPE 为  $5$  ，则表示预测结果较真实结果平均偏离  $5%$  。MAPE 的计算公式如下： \n",
    "\n",
    "$$ \\textrm{MAPE}(y, \\hat{y} ) = \\frac{\\sum_{i=1}^{n}{|\\frac{y_{i}-\\hat y_{i}}{y_{i}}|}}{n} \\times 100 \\tag{3} $$ \n",
    "\n",
    "对于以上 3 个公式，  $y_{i}$  表示真实值，  $\\hat y_{i}$  表示预测值，  $n$  则表示值的个数。3 个评估值越小，说明预测模型拥有更好的精确度。 \n",
    "\n",
    "其中，scikit-learn 提供了 MAE 和 MSE 计算方法如下： "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "89688a04",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'sklearn' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mNameError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[18]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43msklearn\u001b[49m.metrics.mean_absolute_error(y_true, y_pred)  \u001b[38;5;66;03m# MAE 计算\u001b[39;00m\n\u001b[32m      2\u001b[39m sklearn.metrics.mean_squared_error(y_true, y_pred)  \u001b[38;5;66;03m# MSE 计算\u001b[39;00m\n",
      "\u001b[31mNameError\u001b[39m: name 'sklearn' is not defined"
     ]
    }
   ],
   "source": [
    "sklearn.metrics.mean_absolute_error(y_true, y_pred)  # MAE 计算\n",
    "sklearn.metrics.mean_squared_error(y_true, y_pred)  # MSE 计算"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "90576b7f",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "而关于 MAPE 的计算方法，虽然 scikit-learn 未直接提供，但我们已经学会了如何用公式实现。 \n",
    "\n",
    "上面的三个公式，实际上往往仅能用于评价模型的相对优劣，比如多项式回归比线性回归应用于同一组数据结果更好。但如果我们要评价某模型是否真能够很好地解释样本数据，就需要通过一系列的 [ 假设检验 ](https://zh.wikipedia.org/wiki/%E5%81%87%E8%A8%AD%E6%AA%A2%E5%AE%9A) 手段来完成了。 \n",
    "\n",
    "##  8.3.  拟合优度检验  # \n",
    "\n",
    "当我们使用回归分析拟合数据时，实际上是通过样本所估计的参数来代替了总体的真实参数。尽管从统计性质上可知，当进行足够多的重复抽样操作后，参数估计值的期望就等于其总体的真实参数。但实际上，单次抽样过程中，参数的估计值和真实值可能存在差异。 \n",
    "\n",
    "那么，单次抽样后，参数的估计值与真实值差异是否显著，就需要进行统计检验。实际上，在一元线性回归模型中，一般需要：拟合优度检验、变量的显著性检验及参数的区间估计。在多元线性回归模型中，往往会有：拟合优度检验、变量的显著性检验（T 检验）、方程的显著性检验（F 检验）及参数的置信区间。其中，一元线性回归中的 T 检验和 F 检验一致。 \n",
    "\n",
    "一元线性回归的拟合优度检验，指的是对样本回归拟合直线与样本观测值之间拟合程度进行检验。我们一般会使用判定系数  $R^2$  作为度量拟合优度的指标。 \n",
    "\n",
    "假设，我们有一组样本观测值  $(x_i,y_i)$  ，其得到线性回归拟合直线为： \n",
    "\n",
    "$$ \\hat{y}_{i}=w x_{i}+b \\tag{4} $$ \n",
    "\n",
    "此时，如果样本观测值的均值（观测均值）为：  ${\\displaystyle{\\bar{y}}={\\frac{1}{n}}\\sum_{i=1}^{n}y_{i}}$  ，我们定义第  $i$  个观测值与样本均值之间的「离差」为：  $Y_{i}=y_{i}-\\overline{y}$  。 \n",
    "\n",
    "「离差」进而可以分解为： \n",
    "\n",
    "$$ Y_{i}=y_{i}-\\overline{y}=\\left(y_{i}-\\hat{y}_{i}\\right)+\\left(\\hat{y}_{i}-\\overline{y}\\right)=e_{i}+\\hat{Y}_{i} \\tag{5} $$ \n",
    "\n",
    "其中，  $\\hat{Y}_{i}=\\left(\\hat{y}_{i}-\\overline{y}\\right)$  是样本回归拟合值与观测均值之差。我们可以认为这是由回归直线解释的部分。 \n",
    "\n",
    "而，  $e_{i}=\\left(y_{i}-\\hat{y}_{i}\\right)$  是实际观测值与样本回归拟合值之差，也就是「残差」。当  $y_{i}=\\hat{y}_{i}$  时，即实际观测值正好落在样本回归拟合直线上，这是最佳拟合状态。可认为，「离差」全部来自回归线，而与「残差」无关。我们可以认为这是由回归直线不能解释的部分。 \n",
    "\n",
    "![image](https://cdn.aibydoing.com/aibydoing/images/document-uid214893labid7506timestamp1546049497983.svg)\n",
    "\n",
    "那么，我们就记作： \n",
    "\n",
    "$$ TSS=\\sum_{i=1}^{n} Y_{i}^{2}=\\sum_{i=1}^{n}\\left(y_{i}-\\overline{y}\\right)^{2} \\tag{6} $$ \n",
    "\n",
    "$$ E S S=\\sum_{i=1}^{n} \\hat{Y}_{i}^{2}=\\sum_{i=1}^{n}\\left(\\hat{y}_{i}-\\overline{y}\\right)^{2} \\tag{7} $$ \n",
    "\n",
    "$$ RSS=\\sum_{i=1}^{n} e_{i}^{2}=\\sum_{i=1}^{n}\\left(y_{i}-\\hat{y}_{i}\\right)^{2} \\tag{8} $$ \n",
    "\n",
    "我们可以继续推导上述三者之间得关系。其中： \n",
    "\n",
    "$$ TSS=\\sum_{i=1}^{n}\\left(y_{i}-\\bar{y}\\right)^{2} = \\sum_{i=1}^{n}\\left(\\left(y_{i} - \\hat{y}_{i}\\right) + \\left(\\hat{y}_{i} -\\bar{y}\\right)\\right)^{2} $$ \n",
    "\n",
    "$$ =\\sum_{i=1}^{n}\\left(y_{i}-\\hat{y}_{i}\\right)^{2}+\\sum_{i=1}^{n}\\left(\\hat{y}_{i}-\\bar{y}\\right)^{2}+2 \\sum_{i=1}^{n}\\left(y_{i}-\\hat{y}_{i}\\right)\\left(\\hat{y}_{i}-\\bar{y}\\right) \\tag{9} $$ \n",
    "\n",
    "对于线性回归模型  $y_i=w x_{i}+b$  ，当使用最小二乘法估计参数时： \n",
    "\n",
    "$$ Q\\left(b, w\\right)=\\min _{b, w} Q\\left(b, w\\right)=\\sum_{i=1}^{n}\\left(y_{i}-b-w x_{i}\\right)^{2} \\tag{10} $$ \n",
    "\n",
    "那么，公式  $(10)$  存在极小值的必要条件为： \n",
    "\n",
    "$$ \\frac{\\partial Q}{\\partial b}=-2 \\sum_{i=1}^{n}\\left(y_{i}-b-w x_{i}\\right)=0 \\tag{11} $$ \n",
    "\n",
    "$$ \\frac{\\partial Q}{\\partial w}=-2 \\sum_{i=1}^{n} x_{i} \\left(y_{i}-b-w x_{i}\\right)=0 \\tag{12} $$ \n",
    "\n",
    "现在重新回到公式  $(9)$  的第三项，我们省去常数系数继续推导。由于： \n",
    "\n",
    "$$ \\sum_{i=1}^{n}\\left(y_{i}-\\hat{y}_{i}\\right)\\left(\\hat{y}_{i}-\\bar{y}\\right)=\\sum_{i=1}^{n}\\left(y_{i}-b-w x_{i}\\right)\\left(b+w x_{i}-\\bar{y}\\right) $$ \n",
    "\n",
    "$$ =b\\sum_{i=1}^{n}\\left(y_{i}-b-w x_{i}\\right) + w\\sum_{i=1}^{n}x_{i}\\left(y_{i}-b-w x_{i}\\right)-\\bar{y}\\sum_{i=1}^{n}\\left(y_{i}-b-w x_{i}\\right) \\tag{13} $$ \n",
    "\n",
    "公式  $(13)$  中，第一项和第三项根据公式  $(11)$  可知为 0，第二项根据公式  $(12)$  可知为 0。所以，公式  $(13)$  同样为 0。 \n",
    "\n",
    "因此，公式  $(9)$  可以写作： \n",
    "\n",
    "$$ \\sum_{i=1}^{n}\\left(y_{i}-\\bar{y}\\right)^{2}=\\sum_{i=1}^{n}\\left(y_{i}-\\hat{y}_{i}\\right)^{2}+\\sum_{i=1}^{n}\\left(\\hat{y}_{i}-\\bar{y}\\right)^{2} \\tag{14} $$ \n",
    "\n",
    "即证得： \n",
    "\n",
    "$$ TSS=ESS+RSS \\tag{15} $$ \n",
    "\n",
    "其中，TSS 被称之为总体平方和 Total Sum of Squares，ESS 被称之为回归平方和 Explained Sum of Squares，而 RSS 则是残差平方和 Residual Sum of Squares。于是，对于  $y$  的观测值围绕其均值的总离差可分解为两部分：一部分来自回归拟合线 ESS，另一部分则来自随机势力 RSS。 \n",
    "\n",
    "在给定样本中，TSS 不变，如果实际观测点离样本回归拟合线越近，则 ESS 在 TSS 中占的比重越大。因此，我们定义拟合优度等于回归平方和 ESS 与  $y$  的总离差 TSS 的比值。 \n",
    "\n",
    "$$ R^{2}=\\frac{ESS}{TSS}=1-\\frac{RSS}{TSS} \\tag{16} $$ \n",
    "\n",
    "简而言之，当 RSS 越小时，  $R^{2}$  就越趋近于 1，那么代表模型的解释力越强。反之，模型的解释力就越弱。 \n",
    "\n",
    "所以，一般情况下，  $R^{2}$  的有效取值范围在  $[0, 1]$  之间。值越大，就代表模型的拟合优度越好。 \n",
    "\n",
    "接下来，我们通过一个例子，来计算线性回归的模型拟合优度。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "f8436199",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "# 生成 2 组 x 相同的示例数据\n",
    "x = np.array([4, 8, 12, 25, 32, 43, 58, 63, 69, 79]).reshape(-1, 1)\n",
    "y1 = np.array([9, 17, 23, 51, 62, 83, 115, 125, 137, 159]).reshape(-1, 1)\n",
    "y2 = np.array([20, 33, 50, 56, 42, 31, 33, 46, 65, 75]).reshape(-1, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "84baafb2",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x24aaa2f93d0>"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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VfmOv/zlL667D68jR45Y/fv3t+68805r69at1ieffGK9+eab1v79+133HlBbW+v3umzYsMG8p23atMl1r81jjz1mxcfHW+vXr7cqKyuttWvXWr169bKeeeYZ170ucAb6emf+vtPXO/d+gqm/p6935uvyWID7egLts6x159vc3GwlJSVZ//qv/+orq6urs6Kioqzf/va3ltPpL6Pe0+bNm33Xrh2Y/iB77dmzx7QpLS21nO6cc86x/v3f/92193H06FHrggsuMG+KV199ta/zddP9aMc7ZMiQNuvcdB9eP/3pT63Ro0e3W+/m9wD9+Ro4cKC5B7e9NuPGjbPuuusuv7JJkyZZU6ZMcf3rgsCjr3c2+npnCKb+nr7ema/LuAD39UwdD7DKykqprq420xS8YmNjZeTIkVJaWipOV19fbx7j4uLMY1lZmTQ1Nfndj04DSk1NdfT96NSSl156SY4fP26mlbn1PnQqz7hx4/yuW7ntfnTKjk6/PP/882XKlCly8OBBV96Heu2112T48OFy2223mSmYl112mTz33HOufw84ceKErF69Wu666y4zpcxtr80VV1whJSUlsnfvXnP+wQcfyLvvvis33nijq18XOJPbf57o650lWPr6YOrv6eud+bpcEeC+PqLTz4BO0RdXJSYm+pXrubfOqZqbm826oCuvvFIGDRpkyvSau3fvLn369HHF/Xz44Yems9X1JrrOpLCwUDIyMmTnzp2uug+lfzyUl5fL9u3bT6lz0+uib27PP/+8XHTRRVJVVSWLFi2S7373u7Jr1y5X3YfXJ598YtYIzp8/X372s5+Z1+eee+4x9zFt2jTXvgfo+tO6ujq58847zbnbXpsHH3xQGhoazB8I3bp1M3+AP/bYY+YPPeXW1wXO5OafJ/p6ZwmWvj7Y+nv6emfex4MB7usJtNGpT1T1zVA/GXIrfXPXjlY/rf/d735n3gw3b94sbnPo0CG59957ZcOGDRIdHS1u5v2UUWkCG+2I+/fvLy+//LJJUuE2+keqfsr9+OOPm3P9lFt/b1asWGF+3txq5cqV5rXSkQg30p+nNWvWSEFBgVx88cXmfUCDCb0fN78ugN3o650jmPr6YOvv6eud6eUA9/VMHQ+wpKQk89g6W5+ee+ucaPbs2bJ+/XrZtGmT9OvXz1eu16zTTPTTLzfcj34q953vfEeGDRtmsqwOGTJEnnnmGdfdh07lqa2tlaFDh0pERIQ59I+IpUuXmq/1kzk33U9L+qnphRdeKPv373fd66I0i6WOnLSUnp7umx7nxveAAwcOyFtvvSX/9E//5Ctz22tz//33m0+6J0+ebDLD/vCHP5R58+aZ9wG3vi5wLrf+PNHXO0sw9/Vu7+/p6515H/cHuK8n0A4wTTevL6SuH/DSKQ5bt24105ycRnO8aMer0642btxorr8l7cQiIyP97ke3BNE3GifeT1ufSDY2NrruPsaMGWOmxukndd5DP1nVqTHer910Py0dO3ZMPv74Y9OJue11UTrdsvW2OLpWSD+1d+N7gFq1apVZg6ZrBL3c9tp8+eWXEh7u3wXqtDJ9D3Dr6wLnctvPE329M+8jmPt6t/f39PXOfF2+DHRf3+l0ajit7JB//OMfzaHf8qeeesp8feDAAV9a+T59+livvvqq9ac//cmaMGGCI9P9q5kzZ5oU+G+//bZf6v8vv/zS10bT/us2IBs3bjRp/zMzM83hNA8++KDJoKrp/vX7rudhYWHWH/7wB1fdR3taZiJ10/3cd9995udLX5f33nvPysrKsr71rW+ZrLduuo+WW7BERESYLSb27dtnrVmzxvqHf/gHa/Xq1b42bnoPOHnypPn+a4bV1tz02kybNs369re/7dvyQ7dk0p+zBx54wJWvCwKPvt6Zv+/09c69n2Dq7+nrnfm6TAtwX0+gfRbovnPa6bY+9MX3ppZfsGCBlZiYaNLJjxkzxuz16ERt3Yceut+ml/5g/vjHPzbbZ+ibzC233GI6aKfRdP+652H37t2tc88913zfvR2vm+7jdDtft9zP7bffbiUnJ5vXRd8c9bzlPpRuuY+WioqKrEGDBpnf77S0NOvZZ5/1q3fTe4DuC6q/821dn5tem4aGBvP7oX8sREdHW+eff77ZA7mxsdGVrwsCj77emb/v9PXOvZ9g6+/p652nIcB9fZj+p/Pj4gAAAAAAQLFGGwAAAAAAGxFoAwAAAABgIwJtAAAAAABsRKANAAAAAICNCLQBAAAAALARgTYAAAAAADYi0AYAAAAAwEYE2gAAAAAA2IhAGwAAAAAAGxFoAwAAAABgIwJtAAAAAADEPv8H+dL5++HrzUYAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 1200x400 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "# 两组数据分别绘制子图\n",
    "fig, axes = plt.subplots(1, 2, figsize=(12, 4))\n",
    "axes[0].scatter(x, y1)\n",
    "axes[1].scatter(x, y2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40ef893b",
   "metadata": {},
   "source": [
    "以下是代码的详细解释：\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "48f0db4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "from matplotlib import pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b4bc7b59",
   "metadata": {},
   "source": [
    "- 这行代码导入了 `matplotlib.pyplot` 模块，并将其命名为 `plt`，这是一个常见的约定。`matplotlib.pyplot` 是一个用于绘制图形的模块，提供了类似 MATLAB 的绘图功能。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3815f7ea",
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a16104bc",
   "metadata": {},
   "source": [
    "- 这是一个 Jupyter Notebook 的魔法命令，用于在 Notebook 中直接显示绘图结果，而不是弹出一个单独的窗口。它使绘图嵌入在 Notebook 的输出单元中。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d30314dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, axes = plt.subplots(1, 2, figsize=(12, 4))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9205c5c",
   "metadata": {},
   "source": [
    "- `plt.subplots` 用于创建一个包含子图的图形对象。\n",
    "  - `1, 2` 表示创建 1 行 2 列的子图布局。\n",
    "  - `figsize=(12, 4)` 指定整个图形的宽度为 12 英寸，高度为 4 英寸。\n",
    "  - `fig` 是图形对象，`axes` 是一个包含两个子图的数组。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "18ac8664",
   "metadata": {},
   "outputs": [],
   "source": [
    "axes[0].scatter(x, y1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a65e375",
   "metadata": {},
   "source": [
    "- 在第一个子图 (`axes[0]`) 上绘制散点图。\n",
    "  - `x` 是横坐标数据。\n",
    "  - `y1` 是纵坐标数据。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c474c481",
   "metadata": {},
   "outputs": [],
   "source": [
    "axes[1].scatter(x, y2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a026de86",
   "metadata": {},
   "source": [
    "- 在第二个子图 (`axes[1]`) 上绘制散点图。\n",
    "  - `x` 是横坐标数据。\n",
    "  - `y2` 是纵坐标数据。\n",
    "\n",
    "### 总结\n",
    "这段代码的作用是：\n",
    "1. 创建一个包含两个子图的图形。\n",
    "2. 在第一个子图中绘制 `x` 和 `y1` 的散点图。\n",
    "3. 在第二个子图中绘制 `x` 和 `y2` 的散点图。\n",
    "\n",
    "注意：代码中未定义 `x`, `y1`, 和 `y2`，需要确保这些变量在运行代码前已被赋值为有效的数据。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "21f75e10",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-4 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-4 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-4 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-4 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-4 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-4 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-4 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-4 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-4 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-4 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-4 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-4 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-4 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-4 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-4\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>LinearRegression()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-4\" type=\"checkbox\" checked><label for=\"sk-estimator-id-4\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>LinearRegression</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.linear_model.LinearRegression.html\">?<span>Documentation for LinearRegression</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>LinearRegression()</pre></div> </div></div></div></div>"
      ],
      "text/plain": [
       "LinearRegression()"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "\n",
    "model1 = LinearRegression()  # 线性模型 1\n",
    "model1.fit(x, y1)\n",
    "\n",
    "model2 = LinearRegression()  # 线性模型 2\n",
    "model2.fit(x, y2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "b8c4d871",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x24aaa3e8f50>]"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA9oAAAFfCAYAAACx9bQFAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAX+NJREFUeJzt3QmczfX+x/H3zNjDyIghS1JZkl3SqpClqEv9I4pSSshSct0W6VZEuywlUdlKpaIbV0R1s0uFUqQoM1QylhrLzPk/Pr9vszHKcGZ+58x5PR+Pc+f8vr+f6et3Z3zP5/f9fj+fqEAgEBAAAAAAAAiK6OB8GwAAAAAAYAi0AQAAAAAIIgJtAAAAAACCiEAbAAAAAIAgItAGAAAAACCICLQBAAAAAAgiAm0AAAAAAIKogMJQamqqtm3bphIlSigqKsrv7gAAoEAgoD179qhChQqKjuY59olirAcAhPNYH5aBtg28lSpV8rsbAAAcYevWrapYsaLf3Qh7jPUAgHAe68My0Lan22l/wZIlS/rdHQAAtHv3bi8wTBujcGIY6wEA4TzWh2WgnbaEzAZeBl8AQChhmXNwMNYDAMJ5rGcTGQAAAAAAQUSgDQAAAABAEBFoAwAAAAAQRATaAAAAAAAEEYE2AAAAAABBRKANAAAAAEAQhWV5LwAAAABA7ktJDWj55p3asSdZZUsU0blVSysmmlKWf4dAGwAAAABwhLlrEzRs9nolJCWnt5WPLaKh7Wqpde3yvvYt1LF0HAAAAABwRJDda8rqLEG2SUxK9trtPI6OQBsAELn++MPvHgAAEJLLxW0mO5DNubQ2O2/XIXsE2gCAyLRkiVSrljRzpt89AQAgpNie7MNnsjOz8NrO23XIHoE2ACCypKRIjz4qXXSR9P330vDhUmqq370CACBkWOKzYF4XiQi0AQCRY9s26fLLpXvvdQF3587Shx9K0QyHAACkseziwbwuEvHJAgAQGd57T6pbV1q4UCpWTJo0SZo6VYqN9btnAACEFCvhZdnFj1bEy9rtvF2HIAXaH330kdq1a6cKFSooKipKb7/9dpbz1pbda9SoUenXnHbaaUecHzFiRE67AgDA39u/X+rfX7rySumXX6R69aTVq6Xu3W3Q8rt3AACEHKuTbSW8zOEjZdqxnaeedhAD7X379qlu3boaM2ZMtucTEhKyvF566SUvkO7YsWOW6x566KEs1/Xt2zenXQEA4K99843UtKn0zDPuuF8/aelSqXp1v3sGAEBIszrZ47o2UHxs1uXhdmzt1NH+awWUQ23atPFeRxMfH5/l+J133tGll16q008/PUt7iRIljrj2aPbv3++90uzevTun3QYARJJAQHr5ZalPH3tCLJUp45aK26w2AAA4JhZMt6wV72UXt8Rntifbloszk+3zHu3t27frvffeU48ePY44Z0vF4+LiVL9+fW9Z+aFDh476fYYPH67Y2Nj0V6VKlXKz2wCAcGYPY7t0kW66yQXZl14qff45QTYAAMfBguqm1eJ0Vb1Tva8E2bk0o50TL7/8sjdz3aFDhyztd955pxo0aKDSpUvr008/1ZAhQ7zl408++WS238fODxw4MMuMNsE2AOAIy5e7TOLffSfFxNg+JWnwYPceAAAgPwTatj+7S5cuKlIk67r+zEFznTp1VKhQId12223ezHXhwoWP+D7Wll07AAAeq4P9+OOubJetkKpSRZo+3e3PBgAAyC9Lxz/++GNt2LBBt9xyy99e26RJE2/p+Pfff59b3QEA5FeJiVLr1m7m2oLsa6+V1qwhyAYAAPkv0J44caIaNmzoZSj/O2vWrFF0dLTKli2bW90BAORHc+e62tjz50tFi0oTJkivvSaVKuV3zwAAQATL8dLxvXv3auPGjenHmzdv9gJl229duXLl9D3UM2fO1BNPPHHEn1+yZImWLVvmZSK3/dt2PGDAAHXt2lUnn3zyif59AACR4MAB6V//ktLGmTp1pBkzpJo1/e4ZAABAzgPtlStXekHy4futu3XrpsmTJ3vvZ8yYoUAgoM6WkOYwttfazj/44INeya6qVat6gXbmfdsAAByVPezt1ElatcodWwmvUaOkw/KBAAAA+CUqYBFxmLEZcyvzlZSUpJIlS/rdHQBAXpkyRerVy5ZXSaVLW9ZN6aqrFAoYm4KL+wkACOexKVezjgMAEBR79ki9e0uvvuqOL75YmjpVqljR754BAADkXTI0AACCwpaIN2jgguzoaFcbe+FCgmwAABCymNEGAIRubeynn5b++U/p4EGpUiVp2jTpwgv97hkAAMBfItAGAISeHTssy6Yr32U6dHClu2xfNgAAQIhj6TgAILR88IGrjW1BtmUSHz9eeuMNgmwAABA2CLQBAKHBlofbMvHLL5cSE6Wzz5ZWrJBuu02KivK7dwAAAMeMpeMAAP99953UubO0fLk7vv126YknpGLF/O4ZAABAjhFoAwD8NX26m7W2El6lSkkvvih17Oh3rwAAAI4bS8cBAP7Yu1e6+Wbp+utdkH3BBdLnnxNkh4HTTjtNUVFRR7x6W61zScnJyd77uLg4FS9eXB07dtT27dv97jYAAHmGQBsAkPfWrJEaNZImTXK1sR94QFq0SKpc2e+e4RisWLFCCQkJ6a/58+d77ddee633dcCAAZo9e7ZmzpypxYsXa9u2bepgmeMBAIgQLB0HAOSdQEAaPVoaNEg6cEA69VRp6lTpkkv87hly4JRTTslyPGLECFWrVk2XXHKJkpKSNHHiRE2bNk2XXXaZd37SpEmqWbOmli5dqvPOO8+nXgMAkHeY0QYA5I2ff5batZP69XNBdvv2bqk4QXZYO3DggKZMmaKbb77ZWz6+atUqHTx4UC1atEi/pkaNGqpcubKWLFly1O+zf/9+7d69O8sLAIBwRaANADhuKakBLdn0q95Z85P31Y6z9eGHrjb2e+9JhQtLzz0nvf22FBeX111GkL399tvatWuXunfv7h0nJiaqUKFCKmWJ7TIpV66cd+5ohg8frtjY2PRXpUqVcr3vAADkFpaOAwCOy9y1CRo2e70SkpLT28rHFtHQdrXUunb5jNrYw4ZJjz7qlo3XqCHNmOGCbuQLtky8TZs2qlChwgl9nyFDhmjgwIHpxzajTbANAAhXBNoAgOMKsntNWa3D568Tk5K99nFdG6h18f0uo3jacuFbbpGeflo66SQ/uoxc8MMPP+iDDz7QW2+9ld4WHx/vLSe3We7Ms9qWddzOHU3hwoW9FwAA+QFLxwEAOWLLw20mO7tF4mltHz86ToF69VyQHRsrvfaaNGECQXY+Y0nOypYtqyuuuCK9rWHDhipYsKAWLFiQ3rZhwwZt2bJFTZs29amnAADkLWa0AQA5snzzzizLxTMrcjBZDyyYoOs/n+caLMP09OlWeDlvO4lcl5qa6gXa3bp1U4ECGR8nbH91jx49vGXgpUuXVsmSJdW3b18vyCbjOAAgUhBoAwByZMee7IPsGjs2a/S7I3Xmr1uVqiht7NFHZ417QipYMM/7iNxnS8ZtltqyjR/uqaeeUnR0tDp27OhlE2/VqpXGjh3rSz8BAPADgTYAIEfKliiStSEQ0A2fvaf7Fk5U4ZSD2l68tPpfeZfuHHIbQXY+dvnllytgCe6yUaRIEY0ZM8Z7AQAQiQi0AQA5cm7V0l52cUt8FvvHbo18/1ld/u1S79yCao11T9v+KlS+nHcdAABAJCLQBgDkSEx0lFfCa9LwV/TU7MdVYc8v2h9TQCOa3aTJDdtLUVEa166Wdx0AAEAkItAGAOTMoUNqPXO8Ws14WFGpqdpU+lTd2f4erStX7cg62gAAABGIQBsAcOy2bJG6dJE++UQ2X53arbt+GfigeqYW8PZu23JxZrIBAECkI9AGABybWbOkHj2k336TSpSQxo9X9PXXq4nf/QIAAAgx0X53AAAQ4v74Q7rjDqlDBxdkN24sffaZdP31fvcMAAAgJBFoAwCObt06F1iPG+eOBw/2lo2rWjW/ewYAABCyWDoOADiS1Ud+4QWpf38pOVkqV0569VWpZUu/ewYAABDyCLQBAFnZ8vBbb5XefNMdt2olvfyyC7YBAAAQ/KXjH330kdq1a6cKFSooKipKb7/9dpbz3bt399ozv1q3bp3lmp07d6pLly4qWbKkSpUqpR49emjv3r057QoAINhsWXjdui7ILlhQevxx6T//IcgGAADIzUB73759qlu3rsaMGXPUayywTkhISH9Nnz49y3kLstetW6f58+drzpw5XvDes2fPnHYFABAsKSnSv/8tXXKJtHWrdMYZ0qefSnfdJUWTzgMAACBXl463adPGe/2VwoULKz4+PttzX331lebOnasVK1aoUaNGXtvo0aPVtm1bPf74495M+eH279/vvdLs3r07p90GABzNjz9KXbtKixe7Y3s/dqwr4QUAAIAcy5VpikWLFqls2bKqXr26evXqpV9//TX93JIlS7zl4mlBtmnRooWio6O1bNmybL/f8OHDFRsbm/6qVKlSbnQbACLPu++6peIWZBcvLr3yikt6RpANAAAQOoG2LRt/5ZVXtGDBAj322GNavHixNwOeYssSJSUmJnpBeGYFChRQ6dKlvXPZGTJkiJKSktJfW21ZIwDg+Fkm8b59pauussQZUsOG0urV0g03+N0zAADyvZTUgJZs+lXvrPnJ+2rHyF+CnnW8U6dO6e/POecc1alTR9WqVfNmuZs3b35c39OWotsLABAEX31l/1hLX3zhjgcOtKVDUqFCfvcMAIB8b+7aBA2bvV4JScnpbeVji2hou1pqXbu8r31D8OR6hpvTTz9dZcqU0caNG71j27u9Y8eOLNccOnTIy0R+tH3dAIAg1caeOFGyrTsWZJ9yisso/sQTBNkAAORRkN1ryuosQbZJTEr22u088odcD7R//PFHb492+fLu6UzTpk21a9curVq1Kv2ahQsXKjU1VU2aNMnt7gBAZNq1S+rcWbrlFun33y05hgu2/ya5JQAACA5bHm4z2dktEk9rs/MsI4/QQNvqXa9Zs8Z7mc2bN3vvt2zZ4p0bNGiQli5dqu+//97bp33VVVfpjDPOUKtWrbzra9as6e3jvvXWW7V8+XL973//U58+fbwl59llHAcAnKAlS6T69aXXXrOkGNKIEdK8ebbEyO+eAQAQMZZv3nnETHZmFl7bebsOERhor1y5UvXr1/deZuDAgd77Bx54QDExMfriiy/Uvn17nXXWWerRo4caNmyojz/+OMse66lTp6pGjRrenm0r63XhhRfqhRdeCO7fDAAiXWqq23t90UXS999LVatKn3wiDR5MbWwAAPLYjj3JQb0O+SwZWrNmzRSwfX5HMc9mSf6GZRifNm1aTv/TAIBjtW2bdOON0oIF7tiWjY8bJ8XG+t0zAAAiUtkSRYJ6HY6Rxa579kglSyovMaUBAPnNe++52tgWZBcrJk2aZEuJCLIBAPDRuVVLe9nFo45y3trtvF2HIDh0SJoxQ2rcWPq//1NeI9AGgPxi/35pwADpyiulX36R6tVztbG7d5eijjasAwCAvBATHeWV8DKHj8ppx3bersMJsNnrp5+WzjjDreizJNwffSQlJiovEWgDQH7wzTdW1sENLKZfP2npUql6db97BgAA/mR1ssd1baD42KzLw+3Y2qmjfYLb5oYMkSpXdhMPP/zgSpkOG+be53ES2Bzv0QYAhNi+o5dflvr0kfbtk+LipMmT3aw2AAAIORZMt6wV72UXt8Rntifbloszk32c1q2THn/cbZM7eNC1nXmmdNddLl9N0aLyA4E2AISr3bulXr2ktOSSl14qTZkiUSoRAICQZkF102pxfncjvCcaPvzQBdjvv5/RfsEF0qBBUrt2vldYIdAGgHC0fLnbd/Tdd1JMjPTQQ65sl70HAADIjw4elN54wwXYlofGWB6aDh3cDLZtowsRBNoAEG61sW1wufdel02zShU3o33++X73DAAAIPcSnL34ostFs2WL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crn4sHfX6bwfPlfP5W/p0u9WpZ9bVvFsvXhuB61rcJE+vqWFYqLZ0gUgRALt1NRUL9Du1q2bChTI+E9s2rRJ06ZNU9u2bRUXF+ft0R4wYIAuvvhi1alTJze6AvjPAmurI//KK+74ootc0G11NwEAQN46eFCbxkzSC8+O1DnbN3lNKVHRmntWU004t4PWVKjurttzwNu73bRanL/9BRCWciXQtiXjW7Zs8bKNZ2b7te3c008/rX379nn7rDt27Kj77rsvN7oB+G/1aqlTJ+nbb11G0gcekOznndrYAADkrT17pBdf9BKcnbVli9f0R4HCer1OC01sdLW2nHzk6kpLkAYAIRNoX3755coux5oF1osXL86N/yQQWuzn3zKVDh7sPTlXxYquNrbNZgMAgLzz00/S6NHS+PFSkktwdiDuFD1bq5Wm1G+rXUWPntDIspADwPGg6B8QbFau68orpYEDXZD9j39In39OkA0AQF5au1ayErNVq0qPPeaC7OrVpRdeUMyWH/Rmm+5KOkqQbbuyy8e6Ul8AcDwItIFgWrBAqltX+s9/LF2+NHas9OabUmkGagAA8mRFmY3Fbdq48pkvv+weel98sfTuu9L69dKttyqmWFENbefKah6e6izt2M6TCA3A8SLQBoLBBvEhQ6SWLaXERFcTe8UKV3MzikEaAIBcH4dti1bDhlKLFtLcuS43yrXXSkuXSrZ1sV071/an1rXLa1zXBoqPzbo83I6t3c4DQMiV9wIixubNrjb2smXu+LbbpCeflIoV87tnAADkb7t3pyc409atrs3GX0vIO2CAdPrpf/nHLZhuWSveyy5uic9sT7YtF2cmG8CJItAGTsRrr0k9e7qBvlQpacIE6Zpr/O4VAAD5P8HZs89Kzz+fnuBM5cpJfftKt98uxR17SS4LqinhBSDYWDoOHI99+6QePVzpLguyL7hAWrOGIBtARBoxYoSioqLUv3//9Lbk5GT17t1bcXFxKl68uFfOc/v27b72E/nAF19I3bpJp50mjRzpguwaNdys9vffS/fem6MgGwByC4E2kFMWUNsesJdecvuv779fWrRIqlLF754BQJ5bsWKFnn/+edWpUydL+4ABAzR79mzNnDnTK+25bds2dejQwbd+IswTnH3wgdS6tUs4+sor0qFD0iWXSLNnS+vWuYffRSjFBSB0sHQcyMlA/9xz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",
      "text/plain": [
       "<Figure size 1200x400 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 绘制拟合直线到原散点图中\n",
    "fig, axes = plt.subplots(1, 2, figsize=(12, 4))\n",
    "# 模型 1\n",
    "axes[0].scatter(x, y1)\n",
    "axes[0].plot(\n",
    "    [0, 90], [model1.intercept_, model1.coef_[0] * 90 + model1.intercept_], \"r\"\n",
    ")\n",
    "# 模型 2\n",
    "axes[1].scatter(x, y2)\n",
    "axes[1].plot(\n",
    "    [0, 90], [model2.intercept_, model2.coef_[0] * 90 + model2.intercept_], \"r\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f77199e8",
   "metadata": {},
   "source": [
    "这段代码的作用是向第一个子图 (`axes[0]`) 中绘制一条拟合直线。以下是详细解释：\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "146b9919",
   "metadata": {},
   "outputs": [],
   "source": [
    "axes[0].plot(\n",
    "    [0, 90], [model1.intercept_, model1.coef_[0] * 90 + model1.intercept_], \"r\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b11c0d02",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "### 参数解析\n",
    "1. **`[0, 90]`**:\n",
    "   - 这是直线的横坐标范围，表示从 `x=0` 到 `x=90`。\n",
    "\n",
    "2. **`[model1.intercept_, model1.coef_[0] * 90 + model1.intercept_]`**:\n",
    "   - 这是直线的纵坐标范围，计算方式基于线性回归模型 `model1` 的参数：\n",
    "     - `model1.intercept_` 是模型的截距，即当 `x=0` 时的预测值。\n",
    "     - `model1.coef_[0]` 是模型的斜率（回归系数）。\n",
    "     - `model1.coef_[0] * 90 + model1.intercept_` 是当 `x=90` 时的预测值。\n",
    "   - 这两个点定义了一条直线：起点为 `(0, model1.intercept_)`，终点为 `(90, model1.coef_[0] * 90 + model1.intercept_)`。\n",
    "\n",
    "3. **`\"r\"`**:\n",
    "   - 表示直线的颜色为红色 (`r` 是 red 的缩写)。\n",
    "\n",
    "### 整体作用\n",
    "- 这段代码在第一个子图中绘制了一条红色的拟合直线，表示模型 `model1` 的预测结果。\n",
    "- 直线的起点和终点分别由模型的截距和斜率计算得出。\n",
    "\n",
    "### 可视化效果\n",
    "- 直线与散点图结合，可以直观地展示模型 `model1` 的拟合效果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "b5b9b4f6",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.9993315719475073, 0.3740615194558857)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.metrics import r2_score\n",
    "\n",
    "# 分别传入真实观测值和模型预测值\n",
    "r2_score(y1, model1.predict(x)), r2_score(y2, model2.predict(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "810a597a",
   "metadata": {},
   "source": [
    "以下是代码的详细解释：\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0bba24dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import r2_score"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c7919ee",
   "metadata": {},
   "source": [
    "- 从 `sklearn.metrics` 模块中导入了 `r2_score` 函数，用于计算回归模型的 **R²（决定系数）**，这是衡量模型拟合优度的指标。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "63b6142d",
   "metadata": {},
   "outputs": [],
   "source": [
    "r2_score(y1, model1.predict(x)), r2_score(y2, model2.predict(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10e7da8a",
   "metadata": {},
   "source": [
    "- 这行代码分别计算了两个模型的 R² 值，具体解释如下：\n",
    "\n",
    "### 参数解析\n",
    "1. **`y1` 和 `y2`**:\n",
    "   - 真实的观测值（目标值）。\n",
    "\n",
    "2. **`model1.predict(x)` 和 `model2.predict(x)`**:\n",
    "   - 使用模型 `model1` 和 `model2` 对输入数据 `x` 进行预测，得到预测值。\n",
    "\n",
    "3. **`r2_score(y1, model1.predict(x))`**:\n",
    "   - 计算模型 `model1` 的 R² 值，表示模型对数据 `y1` 的拟合优度。\n",
    "\n",
    "4. **`r2_score(y2, model2.predict(x))`**:\n",
    "   - 计算模型 `model2` 的 R² 值，表示模型对数据 `y2` 的拟合优度。\n",
    "\n",
    "### R² 值的意义\n",
    "- R² 值的取值范围为 `[0, 1]`，越接近 1 表示模型的拟合效果越好。\n",
    "- 它表示模型解释了目标变量总变异的比例。\n",
    "\n",
    "### 整体作用\n",
    "- 这段代码的作用是分别计算两个模型（`model1` 和 `model2`）的 R² 值，用于评估它们对数据 `y1` 和 `y2` 的拟合效果。返回的结果是一个元组，包含两个 R² 值。\n",
    "\n",
    "### 注意事项\n",
    "- 确保 `x` 的形状与模型的输入要求一致（例如，可能需要 `x.reshape(-1, 1)`）。\n",
    "- `y1` 和 `y2` 的数据类型和形状应与模型的预测值一致。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "153884d9",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "我们可以使用上面的公式计算方法验证 scikit-learn 计算结果。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "e2a79564",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(0.9993315719475073)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用公式计算方法验证 model1 计算结果\n",
    "rss = np.sum(pow((y1 - model1.predict(x)), 2))\n",
    "tss = np.sum(pow((y1 - np.mean(y1)), 2))\n",
    "1 - rss / tss"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "78b86ca7",
   "metadata": {},
   "source": [
    "以下是代码的详细解释：\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e3d4af29",
   "metadata": {},
   "outputs": [],
   "source": [
    "rss = np.sum(pow((y1 - model1.predict(x)), 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c6a1712",
   "metadata": {},
   "source": [
    "- **`rss`**: Residual Sum of Squares（残差平方和）。\n",
    "  - `y1 - model1.predict(x)`：计算真实值 `y1` 与模型预测值 `model1.predict(x)` 的差值（残差）。\n",
    "  - `pow(..., 2)`：将残差平方。\n",
    "  - `np.sum(...)`：对所有残差平方求和，得到残差平方和 `rss`。\n",
    "  - 这是衡量模型预测值与真实值之间误差的指标，值越小表示模型拟合越好。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "df2e71f9",
   "metadata": {},
   "outputs": [],
   "source": [
    "tss = np.sum(pow((y1 - np.mean(y1)), 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab645ba7",
   "metadata": {},
   "source": [
    "- **`tss`**: Total Sum of Squares（总平方和）。\n",
    "  - `y1 - np.mean(y1)`：计算真实值 `y1` 与其均值的差值。\n",
    "  - `pow(..., 2)`：将差值平方。\n",
    "  - `np.sum(...)`：对所有平方差求和，得到总平方和 `tss`。\n",
    "  - 这是衡量数据总变异程度的指标。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d8d16865",
   "metadata": {},
   "outputs": [],
   "source": [
    "1 - rss / tss"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "048e11b7",
   "metadata": {},
   "source": [
    "- 计算 **R²（决定系数）** 的公式：\n",
    "  - **`R² = 1 - (rss / tss)`**。\n",
    "  - `rss / tss`：表示残差平方和占总平方和的比例。\n",
    "  - `1 - rss / tss`：表示模型解释了目标变量总变异的比例，值越接近 1 表示模型拟合效果越好。\n",
    "\n",
    "### 整体作用\n",
    "- 这段代码通过公式手动计算模型 `model1` 的 R² 值，用于验证 `sklearn.metrics.r2_score` 的计算结果是否一致。\n",
    "\n",
    "### 注意事项\n",
    "1. 确保 `x` 的形状与模型输入一致（例如，可能需要 `x.reshape(-1, 1)`）。\n",
    "2. `np` 是 `numpy` 的别名，需确保已导入 `numpy` 模块：\n",
    "   ```python\n",
    "   import numpy as np\n",
    "   ```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aa3f6220",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "可以看到，模型 1 的  $R^{2}$  结果趋近于 1，而模型 2 的  $R^{2}$  的值则小很多。这代表线性回归模型对第一组数据的解释力较强，而对第二组数据解释力不足。实际上，通过肉眼也可以发现，第二组数据其实更适合于多项式回归模型，而非线性回归模型。这也印证了  $R^{2}$  值的结果。 \n",
    "\n",
    "所以说，虽然采用普通最小二乘估计方法已经能保证模型拟合结果最优，但是依然需要通过「拟合优度检验」来判断该模型是不是能很好地解释数据分布。 \n",
    "\n",
    "这里需要说明的一点，虽然上面说到  $R^{2}$  的有效取值范围在  $[0, 1]$  之间。但 scikit-learn 提供的 API 有可能计算出  $R^{2}$  值为负数的情况。例如下面我们人为设定一条拟合线与样本趋势正好相反，所计算得到的  $R^{2}$  则为负数。这种情况下，  $TSS=ESS+RSS$  的公式也将失去意义。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "7aaf5bf5",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0.5, 1.0, 'r2_score: -3.7404627174607548')"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAigAAAGzCAYAAAAFROyYAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAU4JJREFUeJzt3Qd4VMXXBvA3IZBQg9TQCagU6SWhKIggVZCmglSlF0FAKSpSBALoHxTFICqgdFCQoqB0REInICIdpJiAgISaEMj9njPj5sumkbKbu+X9Pc8luSWb2UL27Mw5Mx6GYRggIiIiciCeZjeAiIiIKD4GKERERORwGKAQERGRw2GAQkRERA6HAQoRERE5HAYoRERE5HAYoBAREZHDYYBCREREDocBChERETkcBihERETkcBigkEPatGkTXn/9dTz55JPIli0bSpUqhZ49eyIsLMzspjmNSZMmoVatWsifPz98fHzwxBNP4M0338Q///zzyJ/dunUrPDw8ktwmTpyY5M/26tVLXfPCCy8ken716tWoVq2aalPx4sUxZswYPHjwINn2POo2b926heHDh8Pf3x/e3t4oUqQI2rdvj7t376b6NXXu3Llk77u0xeL27duq/U2bNkWePHnU+Xnz5iXaxuRu8/nnn0/yvi9cuFBdkyNHjkTPx8TEIDg4GFWqVEHWrFmRN29ePPfcczh06FCC66ZOnaoeI3nsK1WqhMWLF6e5nck9TkuWLEny/kRHR6N8+fLquo8++ijBeXk+evfurdop96d06dIYOnQorl27luRtkmvyMrsBRIkZMWIErl+/jpdeekm9sZ45cwafffYZ1q5di9DQUPj5+ZndRIe3f/9+9abVoUMH5MyZE3/++Se+/PJL/Pjjj+oxzJ49e5I/W65cOcyfPz/BcTn2yy+/oHHjxon+3L59+9QbtLwBJmbdunVo3bo1nn32WXz66af4/fffMWHCBFy5ckW9yablNiMiIlC/fn1cvHhRvbE9/vjjKgj79ddfERUVpYKR1LymJKBL7L6vX79eBQtx7/vVq1cxfvx4FWhVrlxZBXZJSew25b598sknST6eEgBJ4JXccyVBl7Sra9euGDhwIO7cuYODBw+qxzSud999F5MnT1YBVs2aNbFq1Sq8+uqrKlCQ10ha29mxY0c0b97c6ljt2rWTbK887+fPn0/y/srPyn3o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7NgR165dUwHJ008/rUqI5Xsxffp0eHp6qgnapDpH8lQ+//xzWzeDKEUkGKldOq/ZzSCijJY5MzBuHNC0qZ5x9swZ4Nln9YrJ48cDWbKY3UK3x6nuiYjIvcnMs0OGAF9//f8rJi9cCJTXuWrkIlPdExERORVZu+err4AVK4C8eYHQUKB6deDTT/U6P2QKBihERESiTRtdjtykiZ51dtAgmTsDCOPaXGZggEJERGRRqBCwbp3uPfHxAX7+WZcjS+8KZSgGKERERPHLkQcO1FPlV60KXLsGtGsH9Oih81UoQzBAISIiSky5coAsZDtypA5a5szRCbSpmBaD0o4BChERUVKk3DgoCNi6FShRQpcjP/MM8P77ei4VshsGKERERI8iE7gdOqRnnZWJ3T74AKhbFzhxwuyWuSwGKERERCnh6wt8+y2wZIksNAfs3atzVGbPZjmyHTBAISIiSo1XXtHlyA0bAnfvAn36AK1aAVeumN0yl8IAhYiIKLWKFgV++QWYNk3nqaxdq8uR5SvZBAMUIiKitPD01FPk79ungxPpQWnZEujbF7hzx+zWOT0GKEREROkhwcmePcDQoXr/iy90borkqFCaMUAhIiJKL5l19n//AzZuBIoUAU6eBGrXBiZMAB48MLt1TokBChERka1I4uzhw8DLLwMPHwKjR+sS5dOnzW6Z02GAQkREZEt58uhS5PnzgVy5gJAQPQPt3LksR04FBihERES2JlPjd+6se1OkB+X2beD114H27YGrV81unVNggEJERGQvMj3+5s3A5MlA5sx6VeRKlfQqyZQsBihERET2lCkTMGKEXnhQFiAMCwOaNgUGDQLu3TO7dQ6LAQoREVFGqFYN2L8feOMNvf/pp0D16sDBg2a3zCExQCEiIsooWbMCM2YA69YBfn7An38CgYHAlCm66odiMUAhIiLKaDLEI+v5tGkDREcDI0cCzz0H/PWX2S1zGAxQiIiIzJAvH/D998CcOUCOHMD27TqBduFCliMzQCEiIjK5HPm114DQUD3z7M2bujy5Y0fg33/hzhigEBERma10ad2DMn68rvpZulT3pkiJsptigEJEROQIvLz01Pg7dwJPPAFcvKinzn/rLSAqCu6GAQoREZEjCQjQpcd9+uh9WYSwZk2dVOtGGKAQERE5muzZgVmzgNWrgfz5dXAiQcr06UBMDNwBAxQi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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y1)\n",
    "plt.plot([0, 90], [200, -2 * 90 + 200], \"r\")  # 线性函数为：y = -2x + 200\n",
    "plt.title(\"r2_score: {}\".format(r2_score(y1, -2 * x + 200)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "4d51e40d",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([30.12973186,  0.38092285])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import statsmodels.api as sm\n",
    "\n",
    "x = sm.add_constant(x)  # 添加截距项系数 1\n",
    "model = sm.OLS(endog=y2, exog=x)  # 普通最小二乘法, endog 因变量, exog 自变量\n",
    "results = model.fit()\n",
    "results.params  # 输出拟合后系数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ca5008b2",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "outputs": [],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88aa1d89",
   "metadata": {},
   "outputs": [],
   "source": [
    "array([[ 1.,  4.],\n",
    "       [ 1.,  8.],\n",
    "       [ 1., 12.],\n",
    "       [ 1., 25.],\n",
    "       [ 1., 32.],\n",
    "       [ 1., 43.],\n",
    "       [ 1., 58.],\n",
    "       [ 1., 63.],\n",
    "       [ 1., 69.],\n",
    "       [ 1., 79.]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a37344e6",
   "metadata": {},
   "source": [
    "以下是代码的详细解释：\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d6cbd4bf",
   "metadata": {},
   "outputs": [],
   "source": [
    "import statsmodels.api as sm"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf9f9bde",
   "metadata": {},
   "source": [
    "- 导入 `statsmodels` 库的 API 模块，用于统计建模和数据分析。\n",
    "- `statsmodels` 提供了多种统计模型和工具，其中 `OLS` 是用于线性回归的普通最小二乘法模型。\n",
    "\n",
    "---\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c3bf0471",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = sm.add_constant(x)  # 添加截距项系数 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b74329ec",
   "metadata": {},
   "source": [
    "- `sm.add_constant(x)`：在输入数据 `x` 中添加一列常数（通常为 1），用于表示线性回归模型中的截距项。\n",
    "- 截距项是线性回归方程的一部分，形式为：  \n",
    "  **`y = β0 + β1 * x1 + β2 * x2 + ... + ε`**  \n",
    "  其中，`β0` 是截距项。\n",
    "- 如果不添加常数，模型可能会假设截距为 0。\n",
    "\n",
    "---\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2998944b",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = sm.OLS(endog=y2, exog=x)  # 普通最小二乘法, endog 因变量, exog 自变量"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a99c28df",
   "metadata": {},
   "source": [
    "- `sm.OLS`：创建一个普通最小二乘法（Ordinary Least Squares, OLS）模型对象。\n",
    "  - `endog=y2`：因变量（目标变量），即模型要预测的值。\n",
    "  - `exog=x`：自变量（特征变量），即模型的输入数据。\n",
    "- 该模型的目标是通过最小化残差平方和来拟合数据。\n",
    "\n",
    "---\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "72a95882",
   "metadata": {},
   "outputs": [],
   "source": [
    "results = model.fit()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c1696e58",
   "metadata": {},
   "source": [
    "- `model.fit()`：对模型进行拟合，估计模型的参数（如截距和回归系数）。\n",
    "- 返回一个 `RegressionResults` 对象，包含模型的拟合结果和统计信息。\n",
    "\n",
    "---\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "068a2312",
   "metadata": {},
   "outputs": [],
   "source": [
    "results.params  # 输出拟合后系数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47666626",
   "metadata": {},
   "source": [
    "- `results.params`：返回模型拟合后的参数，包括截距和回归系数。\n",
    "  - 参数的顺序与输入数据 `x` 的列顺序一致。\n",
    "  - 例如，第一个参数是截距，后续参数是各自变量的回归系数。\n",
    "\n",
    "---\n",
    "\n",
    "### 整体作用\n",
    "这段代码的作用是：\n",
    "1. 使用 `statsmodels` 库对数据 `x` 和 `y2` 进行线性回归建模。\n",
    "2. 输出模型的拟合参数（截距和回归系数）。\n",
    "\n",
    "### 注意事项\n",
    "1. 确保 `x` 和 `y2` 的数据类型和形状正确。\n",
    "   - `x` 应为二维数组（即每一列是一个特征）。\n",
    "   - `y2` 应为一维数组（目标变量）。\n",
    "2. 如果 `x` 是一维数组，需先转换为二维数组，例如：\n",
    "   ```python\n",
    "   x = x.reshape(-1, 1)\n",
    "   ```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ffab096",
   "metadata": {
    "lines_to_next_cell": 0
   },
   "source": [
    "接下来，我们直接可以输出模型的摘要信息，这也是 statsmodels 的一大特色。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "1e6fdab1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table class=\"simpletable\">\n",
       "<tr>\n",
       "        <td>Model:</td>               <td>OLS</td>         <td>Adj. R-squared:</td>    <td>0.296</td> \n",
       "</tr>\n",
       "<tr>\n",
       "  <td>Dependent Variable:</td>         <td>y</td>               <td>AIC:</td>         <td>83.1646</td>\n",
       "</tr>\n",
       "<tr>\n",
       "         <td>Date:</td>        <td>2025-04-02 11:04</td>        <td>BIC:</td>         <td>83.7698</td>\n",
       "</tr>\n",
       "<tr>\n",
       "   <td>No. Observations:</td>         <td>10</td>          <td>Log-Likelihood:</td>   <td>-39.582</td>\n",
       "</tr>\n",
       "<tr>\n",
       "       <td>Df Model:</td>              <td>1</td>           <td>F-statistic:</td>      <td>4.781</td> \n",
       "</tr>\n",
       "<tr>\n",
       "     <td>Df Residuals:</td>            <td>8</td>        <td>Prob (F-statistic):</td> <td>0.0602</td> \n",
       "</tr>\n",
       "<tr>\n",
       "      <td>R-squared:</td>            <td>0.374</td>            <td>Scale:</td>        <td>200.68</td> \n",
       "</tr>\n",
       "</table>\n",
       "<table class=\"simpletable\">\n",
       "<tr>\n",
       "    <td></td>     <th>Coef.</th>  <th>Std.Err.</th>    <th>t</th>    <th>P>|t|</th> <th>[0.025</th>  <th>0.975]</th> \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>const</th> <td>30.1297</td>  <td>8.1820</td>  <td>3.6824</td> <td>0.0062</td> <td>11.2620</td> <td>48.9975</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>x1</th>    <td>0.3809</td>   <td>0.1742</td>  <td>2.1865</td> <td>0.0602</td> <td>-0.0208</td> <td>0.7827</td> \n",
       "</tr>\n",
       "</table>\n",
       "<table class=\"simpletable\">\n",
       "<tr>\n",
       "     <td>Omnibus:</td>     <td>2.455</td>  <td>Durbin-Watson:</td>   <td>0.832</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <td>Prob(Omnibus):</td>  <td>0.293</td> <td>Jarque-Bera (JB):</td> <td>0.895</td>\n",
       "</tr>\n",
       "<tr>\n",
       "       <td>Skew:</td>     <td>-0.056</td>     <td>Prob(JB):</td>     <td>0.639</td>\n",
       "</tr>\n",
       "<tr>\n",
       "     <td>Kurtosis:</td>    <td>1.538</td>  <td>Condition No.:</td>    <td>86</td>  \n",
       "</tr>\n",
       "</table><br/>\n",
       "Notes:<br/>\n",
       "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified."
      ],
      "text/latex": [
       "\\begin{table}\n",
       "\\caption{Results: Ordinary least squares}\n",
       "\\label{}\n",
       "\\begin{center}\n",
       "\\begin{tabular}{llll}\n",
       "\\hline\n",
       "Model:              & OLS              & Adj. R-squared:     & 0.296    \\\\\n",
       "Dependent Variable: & y                & AIC:                & 83.1646  \\\\\n",
       "Date:               & 2025-04-02 11:04 & BIC:                & 83.7698  \\\\\n",
       "No. Observations:   & 10               & Log-Likelihood:     & -39.582  \\\\\n",
       "Df Model:           & 1                & F-statistic:        & 4.781    \\\\\n",
       "Df Residuals:       & 8                & Prob (F-statistic): & 0.0602   \\\\\n",
       "R-squared:          & 0.374            & Scale:              & 200.68   \\\\\n",
       "\\hline\n",
       "\\end{tabular}\n",
       "\\end{center}\n",
       "\n",
       "\\begin{center}\n",
       "\\begin{tabular}{lrrrrrr}\n",
       "\\hline\n",
       "      &   Coef. & Std.Err. &      t & P$> |$t$|$ &  [0.025 &  0.975]  \\\\\n",
       "\\hline\n",
       "const & 30.1297 &   8.1820 & 3.6824 &      0.0062 & 11.2620 & 48.9975  \\\\\n",
       "x1    &  0.3809 &   0.1742 & 2.1865 &      0.0602 & -0.0208 &  0.7827  \\\\\n",
       "\\hline\n",
       "\\end{tabular}\n",
       "\\end{center}\n",
       "\n",
       "\\begin{center}\n",
       "\\begin{tabular}{llll}\n",
       "\\hline\n",
       "Omnibus:       & 2.455  & Durbin-Watson:    & 0.832  \\\\\n",
       "Prob(Omnibus): & 0.293  & Jarque-Bera (JB): & 0.895  \\\\\n",
       "Skew:          & -0.056 & Prob(JB):         & 0.639  \\\\\n",
       "Kurtosis:      & 1.538  & Condition No.:    & 86     \\\\\n",
       "\\hline\n",
       "\\end{tabular}\n",
       "\\end{center}\n",
       "\\end{table}\n",
       "\\bigskip\n",
       "Notes: \\newline \n",
       "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified."
      ],
      "text/plain": [
       "<class 'statsmodels.iolib.summary2.Summary'>\n",
       "\"\"\"\n",
       "                Results: Ordinary least squares\n",
       "================================================================\n",
       "Model:              OLS              Adj. R-squared:     0.296  \n",
       "Dependent Variable: y                AIC:                83.1646\n",
       "Date:               2025-04-02 11:04 BIC:                83.7698\n",
       "No. Observations:   10               Log-Likelihood:     -39.582\n",
       "Df Model:           1                F-statistic:        4.781  \n",
       "Df Residuals:       8                Prob (F-statistic): 0.0602 \n",
       "R-squared:          0.374            Scale:              200.68 \n",
       "------------------------------------------------------------------\n",
       "           Coef.    Std.Err.     t      P>|t|     [0.025    0.975]\n",
       "------------------------------------------------------------------\n",
       "const     30.1297     8.1820   3.6824   0.0062   11.2620   48.9975\n",
       "x1         0.3809     0.1742   2.1865   0.0602   -0.0208    0.7827\n",
       "----------------------------------------------------------------\n",
       "Omnibus:              2.455        Durbin-Watson:          0.832\n",
       "Prob(Omnibus):        0.293        Jarque-Bera (JB):       0.895\n",
       "Skew:                 -0.056       Prob(JB):               0.639\n",
       "Kurtosis:             1.538        Condition No.:          86   \n",
       "================================================================\n",
       "Notes:\n",
       "[1] Standard Errors assume that the covariance matrix of the\n",
       "errors is correctly specified.\n",
       "\"\"\""
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import warnings\n",
    "\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "results.summary2(alpha=0.05)  # 输出模型摘要, 95% 置信度"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb15f8d5",
   "metadata": {},
   "source": [
    "Model:  |  OLS  |  Adj. R-squared:  |  0.296   \n",
    "---|---|---|---  \n",
    "Dependent Variable:  |  y  |  AIC:  |  83.1646   \n",
    "Date:  |  2023-11-09 14:47  |  BIC:  |  83.7698   \n",
    "No. Observations:  |  10  |  Log-Likelihood:  |  -39.582   \n",
    "Df Model:  |  1  |  F-statistic:  |  4.781   \n",
    "Df Residuals:  |  8  |  Prob (F-statistic):  |  0.0602   \n",
    "R-squared:  |  0.374  |  Scale:  |  200.68   \n",
    "|  Coef.  |  Std.Err.  |  t  |  P>|t|  |  [0.025  |  0.975]   \n",
    "---|---|---|---|---|---|---  \n",
    "const  |  30.1297  |  8.1820  |  3.6824  |  0.0062  |  11.2620  |  48.9975   \n",
    "x1  |  0.3809  |  0.1742  |  2.1865  |  0.0602  |  -0.0208  |  0.7827   \n",
    "Omnibus:  |  2.455  |  Durbin-Watson:  |  0.832   \n",
    "---|---|---|---  \n",
    "Prob(Omnibus):  |  0.293  |  Jarque-Bera (JB):  |  0.895   \n",
    "Skew:  |  -0.056  |  Prob(JB):  |  0.639   \n",
    "Kurtosis:  |  1.538  |  Condition No.:  |  86   \n",
    "  \n",
    "Notes:   \n",
    "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified. \n",
    "\n",
    "重点查看第二个表格，依次得到了拟合系数，标准误差，t 值，p 值，以及置信区间。 \n",
    "\n",
    "\\-  |  Coef.  |  Std.Err.  |  t  |  P>abs(t)  |  [0.025]  |  [0.975]   \n",
    "---|---|---|---|---|---|---  \n",
    "const  |  30.1297  |  8.1820  |  3.6824  |  0.0062  |  11.2620  |  48.9975   \n",
    "x1  |  0.3809  |  0.1742  |  2.1865  |  0.0602  |  -0.0208  |  0.7827   \n",
    "  \n",
    "其中，我们要查看的就是 P 值，如果 P 值很小，那么说明该变量通过显著性检验，需要保留在模型中。实际上，当我们做多元回归建模时，就可以通过查看 P 值，把不显著的变量剔除。 \n",
    "\n",
    "实际上，上面的表格中同时给出了参数检验的置信区间估计。最后两列表示，截距项和自变量系数在 97.5% 的置信度下，置信区间分别为  $(11.2620, 48.9975)$  和  $(-0.0208, 0.7827)$  。 \n",
    "\n",
    "由于置信区间反映了样本参数估计值与总体参数真值的接近程度，因此置信区间越小越好。通常，我们可以通过增大样本容量以及提供模型拟合优度来缩小置信区间。 \n",
    "\n",
    "##  8.5.  总结  # \n",
    "\n",
    "本次实验中，我们复习了前面使用过的回归模型评价指标。但这些指标往往仅能用于模型直接的对比，如果要进一步评价模型的表现就需要对模型进行检验。所以，实验学习了回归模型拟合优度检验和变量显著性检验两类方法。希望大家能对二者有一定的认识，学有余力的同学可以通过文中给出的相关资料，充分了解数理统计学中的相关假设检验原理和方法。 \n",
    "\n",
    "相关链接 \n",
    "\n",
    "  * [ 假设检验-维基百科 ](https://zh.wikipedia.org/wiki/%E5%81%87%E8%A8%AD%E6%AA%A2%E5%AE%9A)\n"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
